<template>
  <el-form
    class="base-form"
    ref="formRef"
    :model="model"
    :rules="rules"
    :label-width="inline ? 'auto' : labelWidth"
    :inline="inline"
    :size="size"
  >
    <slot></slot>
    <template v-for="item in config" :key="item.field">
      <el-form-item :label="item.label" :prop="item.field" v-if="!item.hide">
        <!-- input 输入框 -->
        <template v-if="item.type === 'input'">
          <el-input v-model="model[item.field]" v-bind="item.props" clearable :placeholder="placeholderFormat(item)" />
        </template>
        <!-- input Number 输入框 -->
        <template v-if="item.type === 'inputNumber'">
          <el-input-number class="wfull" v-model="model[item.field]" v-bind="item.props" clearable :placeholder="placeholderFormat(item)" />
        </template>
        <!-- select 普通下拉选择 -->
        <template v-if="item.type === 'select'">
          <el-select v-model="model[item.field]" v-bind="item.props" class="wfull" clearable :placeholder="placeholderFormat(item)">
            <slot name="customSelect">
              <template v-if="isObj(item.options)">
                <el-option v-for="val,key in item.options" :key="key" :label="val" :value="key" />
              </template>
              <template v-else>
                <el-option v-for="obj in item.options" :key="obj.value" :label="obj.label" :value="obj.value" />
              </template>
            </slot>
          </el-select>
        </template>
        <!-- datePicker 日期范围选择 -->
        <template v-if="item.type === 'datePicker'">
          <el-date-picker
            v-model="model[item.field]"
            v-bind="item.props"
            class="wfull"
            :value-format="item.valueFormat || 'x'"
            :type="item.pickType || 'datetimerange'"
            :format="item.format || 'YYYY-MM-DD hh:mm:ss'"
            :placeholder="placeholderFormat(item)"
            :start-placeholder="placeholderFormat(item, 'start')"
            :end-placeholder="placeholderFormat(item, 'end')"
          />
        </template>
        <!-- timePicker 时间选择器 -->
        <template v-if="item.type === 'timePicker'">
          <el-time-picker
            v-model="model[item.field]"
            v-bind="item.props"
            class="wfull"
            range-separator="-"
            :value-format="item.valueFormat || 'x'"
            :format="item.format || 'HH:mm:ss'"
            :placeholder="placeholderFormat(item)"
            :start-placeholder="placeholderFormat(item, 'start')"
            :end-placeholder="placeholderFormat(item, 'end')"
          />
        </template>
        <!-- timeSelect 时间选择 -->
        <template v-if="item.type === 'timeSelect'">
          <el-time-select
            v-model="model[item.field]"
            v-bind="item.props"
            class="wfull"
            start="00:00:00"
            step="00:15:00"
            end="24:00:00"
            format="HH:mm:ss"
            :placeholder="placeholderFormat(item)"
          />
        </template>
        <!-- switch 开关 -->
        <template v-if="item.type === 'switch'">
          <el-switch v-model="model[item.field]" />
        </template>
        <!-- checkbox 多选 -->
        <template v-if="item.type === 'checkbox'">
          <el-checkbox-group v-model="model[item.field]">
            <el-checkbox v-for="obj in item.options" :key="obj.label" :label="obj.value" :name="obj.label">{{ obj.label }}</el-checkbox>
          </el-checkbox-group>
        </template>
        <!-- radio 单选 -->
        <template v-if="item.type === 'radio'">
          <el-radio-group v-model="model[item.field]">
            <el-radio v-for="obj in item.options" :key="obj.label" :label="obj.value" :name="obj.label">{{ obj.label }}</el-radio>
          </el-radio-group>
        </template>
        <!-- upload 图片上传 -->
        <template v-if="item.type === 'upload'">
          <ImageUpload v-model="model[item.field]" :limit="1"></ImageUpload>
        </template>
        <!-- upload 带拖动的图片上传 -->
        <template v-if="item.type === 'uploadImg'">
          <BaseUpload v-model="model[item.field]" :multiple="true" :max="9"></BaseUpload>
        </template>
        <div v-if="item.tip" style="color: #999">{{ item.tip }}</div>
      </el-form-item>
    </template>
    <el-form-item>
      <el-button v-if="config.length" type="primary" @click="submitForm(formRef)">{{ search ? '查询':'确定'}}</el-button>
      <el-button v-if="reset" @click="resetForm(formRef)">重置</el-button>
      <template v-if="buttons && buttons.length">
        <el-button
          v-for="(item, index) in buttons"
          :key="index"
          @click="item.handle(form)"
          :class="item.class || ''"
          :icon="item.icon || ''"
        >
          {{ item.label }}
        </el-button>
      </template>
    </el-form-item>
  </el-form>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import BaseUpload from '@/components/BaseUpload'

const emit = defineEmits([
  'update:modelValue',
  'confirm'
])
const props = defineProps({
  modelValue: {
    type: Object,
    detault: () => {}
  },
  config: {
    type: Array,
    default: () => []
  },
  rules: {
    type: Object,
    detault: () => {}
  },
  inline: Boolean,
  labelWidth: {
    type: String,
    default: '120px'
  },
  size: {
    type: String,
    default: 'default'
  },
  buttons: {
    type: Array,
    default: () => []
  },
  reset: Boolean,
  search: Boolean
})
const formRef = ref()
// 存储表单所有值
let model = reactive({})
function formInit(data) {
  data.forEach(item => {
    model[item.field] = props.modelValue[item.field] || item.default
    if (item.watchField) {
      watch(
        () => model[item.watchField],
        () => {
          item.watchCallBack(model[item.watchField])
          model[item.field] = ''
        }
      )
    }
  })
  emit('update:modelValue', model)
}
onMounted(() => {
  formInit(props.config)
})
watch(
  () => props.modelValue,
  (newValue) => {
    model = newValue
  },
  { immediate: true }
)
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log('submit!', model)
      emit('confirm', model)
    } else {
      console.log('error submit!', fields)
    }
  })
}
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  emit('confirm', model)
}
const resetFields = () => {
  unref(formRef).resetFields()
}
function placeholderFormat(item, flag) {
  const { type, placeholder } = item
  switch(type) {
    case 'input':
    case 'inputNumber':
      return placeholder || '请输入'
    case 'select':
      return placeholder || '请选择'
    case 'timeSelect':
    case 'timePicker':
    case 'datePicker':
      const obj = {
        start: placeholder ? placeholder[0] : '开始时间',
        end: placeholder ? placeholder[1] : '结束时间'
      }
      return flag && obj[flag] || '请选择'
  }
}
function isObj(o) {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Object'
}

defineExpose({ resetFields })
</script>

<style lang="scss">
.base-form {
  .wfull {
    width: 100%;
  }
}
</style>